<?php

declare(strict_types=1);

namespace app\admin\service;

use app\admin\model\ProductMerge as ProductMergeModel;
use app\admin\common\ServiceResponse;
use app\admin\model\Images as ImagesModel;
use app\admin\model\MinerVideos as MinerVideosModel;

class ProductMerge extends BaseService
{
    use ServiceResponse;
    protected $model;
    public function __construct()
    {
        parent::__construct();
        $this->model = new ProductMergeModel();
    }
    /**
     * 注册服务
     *
     * @return mixed
     */
    public function register()
    {
        //
    }

    /**
     * 执行服务
     *
     * @return mixed
     */
    public function boot()
    {
        //
    }

    /**
     * @describe
     * @author: Bobo
     * @date: 2025-02-13 11:03:36
     * @param [type] @required
     * @return Renderable
     */
    public function getFieldEnum($field = 'all')
    {
        $res = $this->model->getFieldEnum($field);
        return $this->success($res);
    }

    public function create($params)
    {

        // 检查商品是否已存在（一次查询检查多个字段）
        $exists = $this->model::where('is_del', 0)
            ->where(function ($query) use ($params) {
                $query->whereOr([
                    'productname' => $params['productname'],
                    'producturlname' => $params['producturlname']
                ]);
            })
            ->field('productname,producturlname')
            ->find();

        if ($exists) {
            if ($exists['productname'] == $params['productname']) {
                return $this->error(500001, '聚合商品名称已存在');
            }
            if ($exists['producturlname'] == $params['producturlname']) {
                return $this->error(500001, 'URL中用的聚合商品名称已存在');
            }
        }

        // 开始事务
        $this->model::startTrans();
        try {
            $sku_list = [];
            $primary_product = $this->model->table('db_product')->where('id', $params['primary_pid'])->where('is_del', 0)->find();
            if (!$primary_product) {
                return $this->error(500001, '主商品不存在');
            }
            $sku_list[] = $params['primary_pid'];
            if (isset($params['vice_pid']) && $params['vice_pid']) {
                $vice_product_ids = $params['vice_pid'];
                $vice_product = $this->model->table('db_product')->whereIn('id', $vice_product_ids)->where('is_del', 0)->count();
                if (count($vice_product_ids) != $vice_product) {
                    return $this->error(500001, '副商品不存在');
                }
                $sku_list = array_merge($sku_list, $vice_product_ids);
            }



            $product_relation = [];
            $storename = $params['storename'];
            unset($params['vice_pid']);
            unset($params['storename']);
            if (isset($params['sales_pids'])) {
                $params['sales_pids'] = implode(',', $params['sales_pids']);
            }
            // if (isset($params['recommend_pids'])) {
            //     $params['recommend_pids'] = implode(',', $params['recommend_pids']);
            // }
            if (isset($params['smv_id'])) {
                $params['smv_id'] = implode(',', $params['smv_id']);
            }

            $res = $this->model->insertGetId($params);

            foreach ($sku_list as  $key => $sku) {
                $product_relation[] = [
                    'pm_id' => $res,
                    'pid' => $sku,
                    'sort' => $key + 1,
                    'creator' => $params['creator'],
                    'create_time' => date('Y-m-d H:i:s'),
                ];
            }

            $this->model->table('db_product_relation')->insertAll($product_relation); // 插入商品关系

            if (count($storename) > 0) {
                $buylink_list = [];
                foreach ($storename as $key => $value) {
                    $buylink_list[] = [
                        'pm_id' => $res,
                        'storename' => $value['value'],
                        'buylink' => $value['buylink'],
                        'status' => $value['status'],
                        'creator' => $params['creator'],
                        'create_time' => date('Y-m-d H:i:s'),
                    ];
                }
                $this->model->table('db_product_merge_buylink')->insertAll($buylink_list);
            }
            $this->clearCTerminalCache(6); // 清除C端产品缓存
            $this->logger->logOperation($res, 'product_merge', '聚合商品', '聚合商品信息创建'); // 记录操作日志
            if ($res) {
                $this->model::commit();
                return $this->success();
            } else {
                return $this->error(500001, '商品创建失败');
            }
        } catch (\Exception $e) {
            $this->model::rollback();
            return $this->error(500001, $e->getMessage());
        }
    }



    /**
     * @describe
     * @author: Bobo
     * @date: 2025-04-07 11:42:03
     * @param [type] @required
     * @return Renderable
     */
    public function update($params)
    {

        // 检查商品是否已存在（一次查询检查多个字段）
        $exists = $this->model::where('is_del', 0)
            ->where('id', '!=', $params['id'])
            ->where(function ($query) use ($params) {
                $query->whereOr([
                    'productname' => $params['productname'],
                    'producturlname' => $params['producturlname']
                ]);
            })
            ->field('productname,producturlname')
            ->find();

        if ($exists) {
            if ($exists['productname'] == $params['productname']) {
                return $this->error(500001, '聚合商品名称已存在');
            }
            if ($exists['producturlname'] == $params['producturlname']) {
                return $this->error(500001, 'URL中用的聚合商品名称已存在');
            }
        }


        $res = $this->getInfo($params)['data'];
        if (!$res) {
            return $this->error(500001, '聚合商品信息不存在');
        }
        $save_data = [];

        foreach ($params as $key => $value) {
            if ($res[$key] != $value) {
                $save_data[$key] = $value;
            }
        }
        if (empty($save_data)) {
            return $this->error(500001, '没有需要更新的数据');
        }

        // 初始化 $sku_list 数组
        $sku_list = [];
        // 检查主商品
        if (isset($save_data['primary_pid'])) {
            $primary_product = $this->model->table('db_product')->where('id', $save_data['primary_pid'])->where('is_del', 0)->find();
            if (!$primary_product) {
                return $this->error(500001, '主商品不存在');
            }
            $sku_list[] = $save_data['primary_pid'];
        } else {
            // 如果没有更新主商品，使用原有的主商品
            $primary_relation = $this->model->table('db_product_relation')
                ->where('pm_id', $params['id'])
                ->where('is_del', 0)
                ->where('sort', 1)
                ->find();
            if ($primary_relation) {
                $sku_list[] = $primary_relation['pid'];
            }
        }

        // 检查副商品
        if (isset($save_data['vice_pid']) && $save_data['vice_pid']) {
            $vice_product_ids = $save_data['vice_pid'];
            $vice_product = $this->model->table('db_product')->whereIn('id', $vice_product_ids)->where('is_del', 0)->count();
            if (count($vice_product_ids) != $vice_product) {
                return $this->error(500001, '副商品不存在');
            }
            $sku_list = array_merge($sku_list, $vice_product_ids);
        }

        $product_relation = [];
        if (!empty($sku_list)) {
            foreach ($sku_list as  $key => $sku) {
                $product_relation[] = [
                    'pm_id' => $params['id'],
                    'pid' => $sku,
                    'sort' => $key + 1,
                    'creator' => $params['updater'],
                    'create_time' => date('Y-m-d H:i:s'),
                ];
            }
        }

        $this->model::startTrans();

        if (isset($save_data['smv_id'])) {
            $save_data['smv_id'] = implode(',', $save_data['smv_id']);
        }
        if (isset($save_data['sales_pids'])) {
            $save_data['sales_pids'] = implode(',', $save_data['sales_pids']);
        }
        // if (isset($save_data['recommend_pids'])) {
        //     $save_data['recommend_pids'] = implode(',', $save_data['recommend_pids']);
        // }

        try {
            // 更新商品关系
            if (isset($save_data['primary_pid']) || isset($save_data['vice_pid'])) {
                // 删除所有旧的关系数据
                $this->model->table('db_product_relation')
                    ->where('pm_id', $params['id'])
                    ->where('is_del', 0)
                    ->update(['is_del' => time()]);

                // 添加新的数据
                if (!empty($product_relation)) {
                    $this->model->table('db_product_relation')->insertAll($product_relation);
                }
            }
            if (isset($save_data['storename']) && count($save_data['storename']) > 0) {
                $this->model->table('db_product_merge_buylink')->where('pm_id', $params['id'])->update(['is_del' => time()]);
                $buylink_list = [];
                foreach ($save_data['storename'] as $key => $value) {
                    $buylink_list[] = [
                        'pm_id' => $params['id'],
                        'storename' => $value['value'],
                        'buylink' => $value['buylink'],
                        'status' => $value['status'],
                        'creator' => $params['updater'],
                        'create_time' => date('Y-m-d H:i:s'),
                    ];
                }
                $this->model->table('db_product_merge_buylink')->insertAll($buylink_list);
            }


            unset($save_data['storename']);
            unset($save_data['vice_pid']);

            // 过滤数据
            $save_data = array_intersect_key($save_data, array_flip($this->model->getUpdateFields()));
            $this->model->where('id', $params['id'])->update($save_data);
            $this->clearCTerminalCache(6); // 清除C端产品缓存
            $this->logger->logOperation($params['id'], 'product_merge', '聚合商品', '聚合商品信息更新'); // 记录操作日志

            $this->model::commit();
            return $this->success();
        } catch (\Exception $e) {
            $this->model::rollback();
            return $this->error(500001, $e->getMessage());
        }
    }


    /**
     * @describe
     * @author: Bobo
     * @date: 2025-04-03 16:03:37
     * @param [type] @required
     * @return Renderable
     */
    public function getList(int $page = 1, int $limit = 10, array $where = [], $field = "*")
    {

        $query = $this->model->alias('pm')
            ->leftJoin('db_product_relation pr', 'pm.id = pr.pm_id')
            ->leftJoin('db_product p', 'pm.primary_pid = p.id')
            ->leftJoin('db_product_brand pb', 'p.brand = pb.id')
            ->field([
                'pm.id',
                'pm.productname',
                'pm.producturlname',
                'pm.primary_pid',
                'pm.sales_pids',
                'pm.product_photo',
                'pm.closeshots_photo',
                'pm.pmv_id',
                'pm.smv_id',
                'pm.describe',
                'pm.full_describe',
                'pm.qanda_describe',
                'pm.seotitle',
                'pm.seodesc',
                'pm.views_number',
                'pm.estimate_price',
                'pm.creator',
                'pm.create_time',
                'pm.updater',
                'pm.update_time',
                'pm.is_del',
                'pm.status',
                'GROUP_CONCAT(pr.pid) as relation_pids',
                'p.type',
                'p.brand',
                'pb.name as brand_name'
            ])
            ->group('pm.id');

        if (!empty($where)) {
            $query->where($where);
        }
        $total = $query->count();
        $list = $query
            ->with(['storename' => function ($query) {
                $query->where('is_del', 0)  // 添加未删除条件
                    ->field(['pm_id', 'storename', 'buylink', 'status']); // 指定需要的字段
            }, 'primaryPid'])
            ->page($page, $limit)
            ->order('pm.id desc')
            ->select()
            ->toArray();

        $env = env('APP_ENV', 'dev');
        $domain = config('domain.' . $env . '.mall');

        foreach ($list as $i => $value) {

            if (!empty($value['storename'])) {
                $storename_vals = [];
                foreach ($value['storename'] as $store) {
                    if ($value['id'] == $store['pm_id']) {
                        $store_label = $this->model->attributes['store'][$store['storename']]['label'] ?? null;
                        if ($store_label !== null) {
                            $storename_vals[] = $store_label;
                        }
                    }
                }
                $list[$i]['storename_val'] = implode(',', $storename_vals);
            } else {
                $list[$i]['storename_val'] = '';
            }

            // 构建外链地址
            $brand_slug = strtolower($value['brand_name'] ?? '');
            if ($value['type'] == 2) { // 配件
                $list[$i]['product_url'] = $domain . '/collections/spare-parts/products/' . $value['producturlname'];
            } else { // 商品
                $list[$i]['product_url'] = $domain . '/collections/' . $brand_slug . '/products/' . $value['producturlname'];
            }
        }
        return $this->success([
            'total' => $total,
            'list' => $list
        ]);
    }



    /**
     * @describe 获取聚合商品信息`
     * @author: Bobo
     * @date: 2025-04-07 11:10:38
     * @param [type] @required
     * @return Renderable
     */
    public function getInfo($params)
    {

        // 获取基本信息
        $res = $this->getBasicInfo($params['id']);

        if (!$res) {
            return $this->error(100001, '聚合商品信息不存在');
        }

        // 处理销售和推荐产品
        $this->processSalesAndRecommendPids($res);

        // 处理视频信息
        $this->processVideoInfo($res);

        // 处理产品关系
        $this->processProductRelation($res);

        // 处理图片信息
        $this->processImageInfo($res);

        // 获取创建者和更新者名称
        $this->addOperatorNames($res);

        // 处理商店名称
        $this->processStoreNames($res);
        return $this->success($res);
    }

    private function getBasicInfo($id)
    {
        return $this->model->where('id', $id)->with(
            [
                'storename' => function ($query) {
                    $query->where('is_del', 0)
                        ->field(['pm_id', 'storename as value', 'buylink', 'status']);
                },
                'primaryPid',
                'productRelation' => function ($query) use ($id) {
                    $query->where('is_del', 0)->where('pm_id', $id);
                },
                'pmvId'
            ]
        )->find()->toArray();
    }

    private function processSalesAndRecommendPids(&$res)
    {
        $salesPidsArray = explode(',', $res['sales_pids']);
        $salesPids = $this->model->table('db_product')->field(['id', 'cname'])
            ->whereIn('id', $salesPidsArray)
            ->where('is_del', 0)
            ->select()
            ->toArray();

        $res['sales_pids'] = array_column($salesPids, 'id');
        $res['sales_pids_list'] = $salesPids;

        // $recommendPidsArray = explode(',', $res['recommend_pids']);
        // $recommendPids = $this->model->table('db_product')->field(['id', 'cname'])
        //     ->whereIn('id', $recommendPidsArray)
        //     ->where('is_del', 0)
        //     ->select()
        //     ->toArray();

        // $res['recommend_pids'] = array_column($recommendPids, 'id');
        // $res['recommend_pids_list'] = $recommendPids;
    }

    private function processVideoInfo(&$res)
    {
        $minerVideoModel = new MinerVideosModel();
        if ($res['pmv_id']) {
            $pmv_id_list = $minerVideoModel->getVideoByIds(strval($res['pmv_id']));
            $res['pmv_id'] =  implode(',', array_column($pmv_id_list, 'id'));
            $res['pmv_id'] = $res['pmv_id'] ? intval($res['pmv_id']) : '';
            $res['pmv_id_list'] = $pmv_id_list;
        }

        if ($res['smv_id']) {
            $smv_id_list = $minerVideoModel->getVideoByIds(strval($res['smv_id']));
            $res['smv_id'] =  array_column($smv_id_list, 'id');
            $res['smv_id'] = $res['smv_id'] ? $res['smv_id'] : [];
            $res['smv_id_list'] = $smv_id_list;
        }
    }

    private function processProductRelation(&$res)
    {
        $vice_pid = [];
        foreach ($res['productRelation'] as &$value) {
            $value['is_primary'] = $value['pid'] == $res['primary_pid'];
            if (!$value['is_primary']) {
                $vice_pid[] = $value['pid'];
            }
            $value['product'] = $value['product']['cname'];
        }
        $res['vice_pid'] = $vice_pid;
    }

    private function processImageInfo(&$res)
    {
        $imagesModel = new ImagesModel();
        $res['product_photo_list'] = $imagesModel->getImagesByIds($res['product_photo']);
        $res['closeshots_photo_list'] = $imagesModel->getImagesByIds($res['closeshots_photo']);
    }

    private function addOperatorNames(&$res)
    {
        $res['creator_name'] = $this->model->table('db_operator')->where('id', $res['creator'])->value('cname');
        $res['updater_name'] = $this->model->table('db_operator')->where('id', $res['updater'])->value('cname');
    }

    private function processStoreNames(&$res)
    {
        $storename_vals = [];
        if (!empty($res['storename'])) {

            foreach ($res['storename'] as &$store) {
                if ($res['id'] == $store['pm_id']) {
                    $store_attributes = $this->model->attributes['storename'][$store['value']] ?? null;
                    if ($store_attributes) {

                        $storename_vals[] = $store_attributes;
                        $store['label'] = $store_attributes;
                        $store['checked'] = true;
                        $store['value'] = intval($store['value']);
                    }
                }
            }
        }
        $res['storename_val'] = implode(',', $storename_vals);
    }

    /**
     * @describe
     * @author: Bobo
     * @date: 2025-04-14 11:20:16
     * @param [type] @required
     * @return Renderable
     */
    public function getSelectData($where = ['is_del' => 0])
    {
        $result = $this->model->where($where)->field('id as value,productname as label')->select()->toArray();
        return $this->success($result);
    }

    public function getSelectedSkuId()
    {
        $res = $this->model->table('db_product_relation')->where('is_del', 0)->field('pid as id')->select()->toArray();
        return $this->success($res);
    }
}
